const std = @import("std");

// 坐标结构
const FCPoint = struct {
    x: f64, // 横坐标
    y: f64, // 纵坐标

    pub fn init(ix: f64, iy: f64) FCPoint {
        return FCPoint{
           .x = ix,
           .y = iy,
        };
    }
};

// 大小结构
const FCSize = struct {
    cx: f64, // 长
    cy: f64, // 宽

    pub fn init(icx: f64, icy: f64) FCSize {
        return FCSize{
           .cx = icx,
           .cy = icy,
        };
    }
};

// 矩形结构
const FCRect = struct {
    left: f64,
    top: f64,
    right: f64,
    bottom: f64,

    pub fn init(ileft: f64, itop: f64, iright: f64, ibottom: f64) FCRect {
        return FCRect{
           .left = ileft,
           .top = itop,
           .right = iright,
           .bottom = ibottom,
        };
    }
};

// 边距信息
const FCPadding = struct {
    left: f64,
    top: f64,
    right: f64,
    bottom: f64,

    pub fn init(ileft: f64, itop: f64, iright: f64, ibottom: f64) FCPadding {
        return FCPadding{
           .left = ileft,
           .top = itop,
           .right = iright,
           .bottom = ibottom,
        };
    }
};

// 绘图结构
const FCPaint = struct {
    cancelClick: bool = false,
    defaultUIStyle: []const u8 = "light",
    dragBeginPoint: FCPoint = FCPoint.init(0, 0),
    dragBeginRect: FCRect = FCRect.init(0, 0, 0, 0),
    draggingView:?*FCView = null,
    editingTextBox:?*FCView = null,
    firstTouch: bool = false,
    focusedView:?*FCView = null,
    isDoubleClick: bool = false,
    isMobile: bool = false,
    isPath: bool = false,
    lastClickTime: u64 = 0,
    moveTo: bool = false,
    offsetX: f64 = 0.0,
    offsetY: f64 = 0.0,
    ratio: f64 = 1,
    resizeColumnState: f64 = 0.0,
    resizeColumnBeginWidth: f64 = 0.0,
    resizeColumnIndex: i32 = -1,
    scaleFactorX: f64 = 1.0,
    scaleFactorY: f64 = 1.0,
    secondTouch: bool = false,
    systemFont: []const u8 = "Arial",
    touchDownPoint: FCPoint = FCPoint.init(0, 0),
    touchFirstPoint: FCPoint = FCPoint.init(0, 0),
    touchSecondPoint: FCPoint = FCPoint.init(0, 0),
    touchDownView:?*FCView = null,
    touchMoveView:?*FCView = null,
    views: []*FCView = &.{},

    // 添加线
    pub fn addLine(self: *FCPaint, x1: f64, y1: f64, x2: f64, y2: f64) void {
    }

    // 开始路径
    pub fn beginPath(self: *FCPaint) void {
    }

    // 开始绘图
    pub fn beginPaint(self: *FCPaint, rect: FCRect) void {
    }

    // 闭合路径
    pub fn closeFigure(self: *FCPaint) void {
    }

    // 关闭路径
    pub fn closePath(self: *FCPaint) void {
    }

    // 绘制线
    pub fn drawLine(self: *FCPaint, color: []const u8, width: f64, style: []f64, x1: f64, y1: f64, x2: f64, y2: f64) void {
    }

    // 绘制路径
    pub fn drawPath(self: *FCPaint, color: []const u8, width: f64, style: []f64) void {
    }

    // 绘制连续线条
    pub fn drawPolyline(self: *FCPaint, color: []const u8, width: f64, style: []f64, apt: []FCPoint) void {
    }

    // 绘制多边形
    pub fn drawPolygon(self: *FCPaint, color: []const u8, width: f64, style: []f64, apt: []FCPoint) void {
    }

    // 绘制图片
    pub fn drawImage(self: *FCPaint, image: anytype, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 绘制矩形
    pub fn drawRect(self: *FCPaint, color: []const u8, width: f64, style: []f64, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 绘制椭圆
    pub fn drawEllipse(self: *FCPaint, color: []const u8, width: f64, style: []f64, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 绘制圆角矩形
    pub fn drawRoundRect(self: *FCPaint, color: []const u8, width: f64, style: []f64, left: f64, top: f64, right: f64, bottom: f64, cornerRadius: f64) void {
    }

    // 绘制文字
    pub fn drawText(self: *FCPaint, text: []const u8, color: []const u8, font: []const u8, x: f64, y: f64) void {
    }

    // 结束绘图
    pub fn endPaint(self: *FCPaint) void {
    }

    // 填充路径
    pub fn fillPath(self: *FCPaint, color: []const u8) void {
    }

    // 填充多边形
    pub fn fillPolygon(self: *FCPaint, color: []const u8, apt: []FCPoint) void {
    }

    // 填充矩形
    pub fn fillRect(self: *FCPaint, color: []const u8, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 填充圆角矩形
    pub fn fillRoundRect(self: *FCPaint, color: []const u8, left: f64, top: f64, right: f64, bottom: f64, cornerRadius: f64) void {
    }

    // 填充椭圆
    pub fn fillEllipse(self: *FCPaint, color: []const u8, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 裁剪
    pub fn setClip(self: *FCPaint, left: f64, top: f64, right: f64, bottom: f64) void {
    }

    // 设置偏移量
    pub fn setOffset(self: *FCPaint, x: f64, y: f64) void {
        self.offsetX = x;
        self.offsetY = y;
    }

    // 获取字体大小
    pub fn textSize(self: *FCPaint, text: []const u8, font: []const u8) FCSize {
        return FCSize.init(0, 0);
    }

    // 保存状态
    pub fn save(self: *FCPaint) void {
    }

    // 恢复状态
    pub fn restore(self: *FCPaint) void {
    }

    // 绘制文字自动省略
    pub fn drawTextAutoEllipsis(self: *FCPaint, text: []const u8, color: []const u8, font: []const u8, left: f64, top: f64, right: f64, bottom: f64) void {
        if (text.len > 0) {
            var tSize = self.textSize(text, font);
            if (tSize.cx < right - left) {
                self.drawText(text, color, font, left, top);
            } else if (tSize.cx > 0) {
                var subLen: usize = 3;
                while (true) {
                    const newLen = text.len - subLen;
                    if (newLen > 0) {
                        const newText = text[0..newLen] ++ "...";
                        tSize = self.textSize(newText, font);
                        if (tSize.cx < right - left) {
                            self.drawText(newText, color, font, left, top);
                            break;
                        } else {
                            subLen += 3;
                        }
                    } else {
                        break;
                    }
                }
            }
        }
    }
};

// 基础视图结构体定义
const FCView = struct {
    allowDrag: bool = false,
    allowResize: bool = false,
    align: []const u8 = "left",
    allowDragScroll: bool = true,
    allowPreviewsEvent: bool = false,
    backColor: []const u8 = "rgb(255,255,255)",
    borderColor: []const u8 = "rgb(150,150,150)",
    borderWidth: f64 = 1,
    clipRect: FCRect = FCRect.init(0, 0, 0, 0),
    cornerRadius: f64 = 0,
    cursor: []const u8 = "",
    downScrollHButton: bool = false,
    downScrollVButton: bool = false,
    displayOffset: bool = true,
    dock: []const u8 = "none",
    enabled: bool = true,
    font: []const u8 = "Default,12",
    hoveredColor:?[]const u8 = null,
    hoverScrollHButton: bool = false,
    hoverScrollVButton: bool = false,
    hScrollIsVisible: bool = false,
    location: FCPoint = FCPoint.init(0, 0),
    margin: FCPadding = FCPadding.init(0, 0, 0, 0),
    maximumSize: FCSize = FCSize.init(0, 0),
    padding: FCPadding = FCPadding.init(0, 0, 0, 0),
    paint:?*FCPaint = null,
    parent:?*FCView = null,
    pushedColor: []const u8 = "rgb(100,100,100)",
    resizePoint: i32 = -1,
    scrollV: f64 = 0.0,
    scrollH: f64 = 0.0,
    scrollSize: f64 = 8.0,
    showHScrollBar: bool = false,
    showVScrollBar: bool = false,
    scrollBarColor: []const u8 = "rgb(200,200,200)",
    scrollBarHoveredColor: []const u8 = "rgb(42,138,195)",
    size: FCSize = FCSize.init(0, 0),
    startScrollH: f64 = 0.0,
    startScrollV: f64 = 0.0,
    startPoint: FCPoint = FCPoint.init(0, 0),
    startRect: FCRect = FCRect.init(0, 0, 0, 0),
    tabIndex: i32 = 0,
    tabStop: bool = false,
    text: []const u8 = "",
    textColor: []const u8 = "rgb(0,0,0)",
    textAlign: []const u8 = "left",
    topMost: bool = false,
    touchDownTime: u64 = 0,
    viewName: []const u8 = "",
    visible: bool = true,
    verticalAlign: []const u8 = "top",
    viewType: []const u8 = "none",
    vScrollIsVisible: bool = false,
    views: []*FCView = &.{},

    pub fn init() FCView {
        return FCView{};
    }
};

// 添加顶层视图
fn addView(view: *FCView, paint: *FCPaint) void {
    view.paint = paint;
    paint.views = std.ArrayList(*FCView).init(std.heap.page_allocator);
    try paint.views.append(view);
}

// 添加到父视图
fn addViewToParent(view: *FCView, parent: *FCView)!void {
    view.paint = parent.paint;
    if (parent.views == null) {
        parent.views = std.ArrayList(*FCView).init(std.heap.page_allocator);
    }
    try parent.views.append(view);
    view.parent = parent;
}

// 清除视图
fn clearViews(paint: *FCPaint) void {
    paint.views = std.ArrayList(*FCView).init(std.heap.page_allocator);
}

// 移除顶层视图
fn removeView(view: *FCView, paint: *FCPaint) void {
    if (paint.views!= null) {
        var i: usize = 0;
        while (i < paint.views.items.len) : (i += 1) {
            if (paint.views.items[i] == view) {
                _ = paint.views.swapRemove(i);
                break;
            }
        }
    }
}

// 从父视图中移除
fn removeViewFromParent(view: *FCView, parent: *FCView) void {
    if (parent.views!= null) {
        var i: usize = 0;
        while (i < parent.views.items.len) : (i += 1) {
            if (parent.views.items[i] == view) {
                _ = parent.views.swapRemove(i);
                break;
            }
        }
    }
}

// 获取绝对位置X
fn clientX(view:?*FCView) f64 {
    if (view) |v| {
        var cLeft = v.location.x;
        if (v.parent) |parent| {
            if (parent.displayOffset and parent.scrollH > 0) {
                cLeft += clientX(parent) - parent.scrollH;
            } else {
                cLeft += clientX(parent);
            }
        }
        return cLeft;
    }
    return 0;
}

// 获取绝对位置Y
fn clientY(view:?*FCView) f64 {
    if (view) |v| {
        var cTop = v.location.y;
        if (v.parent) |parent| {
            if (parent.displayOffset and parent.scrollV > 0) {
                cTop += clientY(parent) - parent.scrollV;
            } else {
                cTop += clientY(parent);
            }
        }
        return cTop;
    }
    return 0;
}

// 是否包含坐标
fn containsPoint(view:?*FCView, mp: FCPoint) bool {
    if (isViewEnabled(view)) {
        var clx = clientX(view);
        var cly = clientY(view);
        var size = view.?.size;
        var cp = FCPoint{
          .x = mp.x - clx,
          .y = mp.y - cly,
        };
        return cp.x >= 0 and cp.x <= size.cx and cp.y >= 0 and cp.y <= size.cy;
    }
    return false;
}

// 判断视图是否可用
fn isViewEnabled(view:?*FCView) bool {
    if (view) |v| {
        if (v.enabled) {
            if (v.parent) |parent| {
                return isViewEnabled(parent);
            }
            return true;
        }
    }
    return false;
}

// 查找有预处理事件的父视图
fn findPreviewsEventParent(view:?*FCView)?*FCView {
    if (view) |v| {
        if (!v.allowPreviewsEvent and v.parent) |parent| {
            if (parent.allowPreviewsEvent) {
                return parent;
            } else {
                return findPreviewsEventParent(parent);
            }
        }
    }
    return null;
}

// 根据名称查找视图
fn findViewByName(name: []const u8, views: []*FCView)?*FCView {
    for (views) |view| {
        if (std.mem.eql(u8, view.viewName, name)) {
            return view;
        }
        if (view.views!= null) {
            if (findViewByName(name, view.views.items)!= null) {
                return findViewByName(name, view.views.items);
            }
        }
    }
    return null;
}

// 根据坐标查找视图
fn findView(mp: FCPoint, views: []*FCView)?*FCView {
    var size: usize = views.len;
    var i: usize = size;
    while (i > 0) : (i -= 1) {
        var view = views[i - 1];
        if (view.visible and view.topMost) {
            var hasPoint = containsPoint(view, mp);
            if (hasPoint) {
                if (view.vScrollIsVisible and view.scrollSize > 0) {
                    var clx = clientX(view);
                    if (mp.x >= clx + view.size.cx - view.scrollSize) {
                        return view;
                    }
                }
                if (view.hScrollIsVisible and view.scrollSize > 0) {
                    var cly = clientY(view);
                    if (mp.y >= cly + view.size.cy - view.scrollSize) {
                        return view;
                    }
                }
                if (view.views!= null) {
                    var subView = findView(mp, view.views.items);
                    if (subView) |sv| {
                        return sv;
                    }
                }
                return view;
            }
        }
    }

    i = size;
    while (i > 0) : (i -= 1) {
        var view = views[i - 1];
        if (view.visible and!view.topMost) {
            var hasPoint = containsPoint(view, mp);
            if (hasPoint) {
                if (view.vScrollIsVisible and view.scrollSize > 0) {
                    var clx = clientX(view);
                    if (mp.x >= clx + view.size.cx - view.scrollSize) {
                        return view;
                    }
                }
                if (view.hScrollIsVisible and view.scrollSize > 0) {
                    var cly = clientY(view);
                    if (mp.y >= cly + view.size.cy - view.scrollSize) {
                        return view;
                    }
                }
                if (view.views!= null) {
                    var subView = findView(mp, view.views.items);
                    if (subView) |sv| {
                        return sv;
                    }
                }
                return view;
            }
        }
    }

    return null;
}

// 是否重绘时可见
fn isPaintVisible(view:?*FCView) bool {
    if (view) |v| {
        if (v.visible) {
            if (v.parent) |parent| {
                if (parent.visible) {
                    return isPaintVisible(parent);
                } else {
                    return false;
                }
            } else {
                return true;
            }
        } else {
            return false;
        }
    }
    return false;
}

// 是否视图可用
fn isViewEnabled(view:?*FCView) bool {
    if (view) |v| {
        if (v.enabled) {
            if (v.parent) |parent| {
                if (parent.enabled) {
                    return isViewEnabled(parent);
                } else {
                    return false;
                }
            } else {
                return true;
            }
        } else {
            return false;
        }
    }
    return false;
}

// 获取区域的交集
fn getIntersectRect(lpDestRect: *FCRect, lpSrc1Rect: FCRect, lpSrc2Rect: FCRect) bool {
    lpDestRect.left = @max(lpSrc1Rect.left, lpSrc2Rect.left);
    lpDestRect.right = @min(lpSrc1Rect.right, lpSrc2Rect.right);
    lpDestRect.top = @max(lpSrc1Rect.top, lpSrc2Rect.top);
    lpDestRect.bottom = @min(lpSrc1Rect.bottom, lpSrc2Rect.bottom);
    return lpDestRect.right > lpDestRect.left and lpDestRect.bottom > lpDestRect.top;
}

// 重绘视图
fn renderViews(views: []*FCView, paint: *FCPaint, rect:?*FCRect) void {
    var viewsSize: usize = views.len;
    var i: usize = 0;
    while (i < viewsSize) : (i += 1) {
        var view = views[i];
        if (rect == null) {
            if (view.views!= null) {
                var subViewsSize: usize = view.views.items.len;
                if (subViewsSize > 0) {
                    renderViews(view.views.items, paint, null);
                }
            }
            view.clipRect = FCRect{
              .left = 0,
              .top = 0,
              .right = 0,
              .bottom = 0,
            };
            continue;
        }
        if (!view.topMost and isPaintVisible(view)) {
            var clx = clientX(view);
            var cly = clientY(view);
            var drawRect = FCRect{
              .left = 0,
              .top = 0,
              .right = view.size.cx,
              .bottom = view.size.cy,
            };
            var clipRect = FCRect{
              .left = clx,
              .top = cly,
              .right = clx + view.size.cx,
              .bottom = cly + view.size.cy,
            };
            var destRect = FCRect{
              .left = 0,
              .top = 0,
              .right = 0,
              .bottom = 0,
            };
            if (getIntersectRect(&destRect, rect.?, clipRect)) {
                paint.save();
                paint.setOffset(0, 0);
                paint.setClip(destRect.left, destRect.top, destRect.right, destRect.bottom);
                view.clipRect = destRect;
                paint.setOffset(clx, cly);
                if (view.views!= null) {
                    var subViewsSize: usize = view.views.items.len;
                    if (subViewsSize > 0) {
                        renderViews(view.views.items, paint, &destRect);
                    }
                }
                paint.setOffset(clx, cly);
                paint.restore();
            } else {
                if (view.views!= null) {
                    var subViewsSize: usize = view.views.items.len;
                    if (subViewsSize > 0) {
                        renderViews(view.views.items, paint, null);
                    }
                }
                view.clipRect = FCRect{
                  .left = 0,
                  .top = 0,
                  .right = 0,
                  .bottom = 0,
                };
            }
        }
    }

    i = 0;
    while (i < viewsSize) : (i += 1) {
        var view = views[i];
        if (rect == null) {
            continue;
        }
        if (view.topMost and isPaintVisible(view)) {
            var clx = clientX(view);
            var cly = clientY(view);
            var drawRect = FCRect{
              .left = 0,
              .top = 0,
              .right = view.size.cx,
              .bottom = view.size.cy,
            };
            var clipRect = FCRect{
              .left = clx,
              .top = cly,
              .right = clx + view.size.cx,
              .bottom = cly + view.size.cy,
            };
            var destRect = FCRect{
              .left = 0,
              .top = 0,
              .right = 0,
              .bottom = 0,
            };
            if (getIntersectRect(&destRect, rect.?, clipRect)) {
                paint.save();
                paint.setOffset(0, 0);
                view.clipRect = destRect;
                paint.setClip(destRect.left, destRect.top, destRect.right, destRect.bottom);
                paint.setOffset(clx, cly);
                if (view.views!= null) {
                    var subViewsSize: usize = view.views.items.len;
                    if (subViewsSize > 0) {
                        renderViews(view.views.items, paint, &destRect);
                    }
                }
                paint.setOffset(clx, cly);
                paint.restore();
            } else {
                if (view.views!= null) {
                    var subViewsSize: usize = view.views.items.len;
                    if (subViewsSize > 0) {
                        renderViews(view.views.items, paint, null);
                    }
                }
                view.clipRect = FCRect{
                  .left = 0,
                  .top = 0,
                  .right = 0,
                  .bottom = 0,
                };
            }
        }
    }
}

// 全局刷新
fn invalidate(paint: *FCPaint) void {
}

// 刷新视图
fn invalidateView(view: *FCView) void {
}